<template>
  <el-select
    ref="select"
    style="width: 200px"
    :clearable="clearable"
    size="small"
    :disabled="dabeld"
    v-model="data"
    :filterable="filterable"
    @focus="handleFocus"
    v-loading="loading && isNotInCommonForm"
    element-loading-spinner="el-icon-loading"
    @change="handleChange"
    :multiple="multiple"
    v-bind="$attrs"
  >
    <el-option
      :disabled="disabledCode.indexOf(item[labelOptions.key]) > -1"
      v-for="item in selectOptions"
      :key="item[labelOptions.key]"
      :label="item[labelOptions.value]"
      :value="item[labelOptions.key]"
    />
    <div class="select-add-container" @click="routerTo" v-if="hasRouter">
      <i class="el-icon-plus" style="color: #0088f7" />
      <span class="select-add-new">新建</span>
    </div>
    <span slot="empty" v-if="hasRouter && selectOptions.length" />
    <div class="select-add-container" @click="routerTo" v-if="hasRouter && selectOptions.length == 0" slot="empty">
      <i class="el-icon-plus" style="color: #0088f7" />
      <span class="select-add-new">新建</span>
    </div>
  </el-select>
</template>

<script>
export default {
  props: {
    value: {
      type: [String, Array, Number, Boolean]
    },
    options: {
      type: Array,
      default: () => []
    },
    query: {
      type: String,
      default: ""
    },
    clearable: {
      type: Boolean,
      default: true
    },
    defaultadd: {
      type: Boolean,
      default: false
    },
    firstVal: {
      type: Boolean,
      default: false
    },
    autoQuery: {
      type: Boolean,
      default: true
    },
    dabeld: {
      type: Boolean,
      default: false
    },
    focusSearch: {
      type: Boolean,
      default: false
    },
    isNotInCommonForm: {
      type: Boolean,
      default: true
    },
    labelOptions: {
      type: Object,
      default: () => ({
        key: "code",
        value: "name"
      })
    },
    hasRouter: {
      type: Boolean,
      default: false
    },
    router: {
      type: Object,
      default: () => ({})
    },
    disabledCode: {
      type: Array,
      default: () => []
    },
    multiple: {
      type: Boolean,
      default: false
    }
  },
  created() {
    if (this.query && this.autoQuery) {
      this.queryOption()
    } else {
      this.selectOptions = this.options
      this.data = this.value
    }
  },
  data() {
    return {
      loading: false,
      data: "",
      selectOptions: [],
      filterable: true
    }
  },
  watch: {
    value(val) {
      this.data = val
    },
    query() {
      if (this.loading || this.autoQuery == false) return
      this.queryOption()
    },
    options(val) {
      this.selectOptions = val
    }
  },
  methods: {
    handleFocus() {
      this.filterable = true
      if (this.focusSearch) {
        this.queryOption()
      }
    },
    routerTo() {
      this.$refs.select.blur()
      const { href } = this.$router.resolve(this.router)
      window.open(href, "_blank")
    },
    clearOption() {
      this.selectOptions = []
    },
    queryOption() {
      this.loading = true
      return this.$ajax
        .get(this.query)
        .then((data) => {
          this.selectOptions = data.data.list || data.data
          this.isload = true
          this.data = this.value
          if (this.defaultadd && this.selectOptions.length == 0) {
            this.selectOptions = [
              {
                code: "add",
                name: "无项目，+立即新建"
              }
            ]
          }
          if (this.firstVal && !this.data) {
            this.data = this.selectOptions[0][this.labelOptions.key]
            this.$emit("input", this.data)
          }
          this.$nextTick(() => {
            this.loading = false
          })
          return Promise.resolve(data.data)
        })
        .catch(() => {
          this.loading = false
        })
    },
    getRaw() {
      let raw
      if (Array.isArray(this.data)) {
        raw = this.data.map((el) => {
          return this.selectOptions.filter((option) => {
            return option[this.labelOptions.key] == el
          })[0]
        })
      } else {
        raw = this.selectOptions.filter((option) => {
          return option[this.labelOptions.key] == this.data
        })[0]
      }
      return raw
    },
    handleChange(value) {
      let name = []
      try {
        name = value && getLabel(this.selectOptions, value, this.labelOptions)
      } catch (err) {
        name = []
      }
      this.filterable = false
      if (!this.multiple) {
        this.$nextTick(() => {
          this.$refs.select.blur()
        })
      }
      this.filterable = true

      const raw = this.getRaw()
      this.$emit("input", value)
      this.$emit("change", value)
      this.$emit("getName", name)
      this.$emit("getRaw", raw)
    },
    clearValue() {
      this.data = null
    }
  }
}
function getLabel(arr, val, labelOptions) {
  if (Array.isArray(val)) {
    return val.map((el) => {
      return getLabel(arr, el, labelOptions)
    })
  } else {
    return arr.filter((el) => {
      return el[labelOptions.key] === val
    })[0][labelOptions.value]
  }
}
</script>
<style lang="less">
@import url("../../styles/var.less");
.select-add-container {
  cursor: pointer;
  font-size: 14px;
  height: 34px;
  padding: 0 20px;
  line-height: 34px;
  &:hover {
    background-color: rgba(43, 160, 255, 0.2);
  }
  .select-add-new {
    display: inline-block;
    color: @blue;
    margin-left: 4px;
  }
}
</style>
